﻿// ----------------------------------------------------------------------
// <author name="Moses Kehengu"/>
// <copyright file="ReportingEngineGUI.cs" company="Futures Group International">
//     Copyright statement. All right reserved
// </copyright>
//
// ------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using GenericTools;
using Reporting;
using GsmComm.GsmCommunication;
using System.IO;
using System.IO.Ports;
using ReportingEngine;
using System.Threading;
using DataModels.Enumerations;
using GenericTools.ReportProcessing;
using DataModels.Common;

namespace ReportingEngineGUI
{
    public partial class ReportingEngineGUI : Form
    {
        #region Class Constants
        private const string CREATE_BACKUP_AFTER = @"CreateBackupAfter";
        private const string COMPRESS_BACKUP = @"CompressBackup";
        private const string BACKUP_FOLDER = @"BackupFolder";
        private const string LAST_BACKUP = @"LastAutoBackupDate";

        private const int MINUTE_MILLISECONDS = 60000;
        #endregion

        #region Class Variables
        private bool configuredModemsLoaded = false;
        private bool forceRestart = false;
        #region Modems Configurations Tab
        private bool tabPageModemsConfigurationLoaded = false;
        private string testedPortName;
        private int testedBaudRate;
        private int testedTimeout;
        private List<Modem> modems = new List<Modem>();
        private bool autoStarted = false;

        private bool tabPageSettingsLoaded = false;
        #endregion

        private Engine reportingEngine = null;
        private AutoReminder autoReminder = null;
        #endregion

        #region Constructors
        public ReportingEngineGUI(bool autoStart)
        {
            InitializeComponent();
            
            logDataTable = new DataTable();
            DataColumn column = new DataColumn("DateTimeColumn", Type.GetType("System.DateTime"));
            logDataTable.Columns.Add(column);
            column = new DataColumn("LogDetailsColumn", Type.GetType("System.String"));
            logDataTable.Columns.Add(column);

            dgvLog.DataSource = logDataTable;

            autoReminder = new AutoReminder();

            this.autoStarted = autoStart;
            LoadConfiguredModems();
            if (modems.Count > 0)
            {
                //btnStartEngine_Click(null, null);
                btnStartEngine.Enabled = true;
                btnStopEngine.Enabled = false;
            }
            else
            {
                btnStartEngine.Enabled = false;
                btnStopEngine.Enabled = false;
            }

            reportingEngine = new Engine(modems, AppConfiguration.SameMonthReporting);
            //reportingEngine.ChangingLog += new ReportingEngine.ChangingLogHandler(reportingEngine_ChangingLog);
            reportingEngine.LogChanged += new EventHandler<ReportingEngineEventArgs>(reportingEngine_LogChanged);

            if (this.autoStarted) btnStartEngine_Click(null, null);
            if (reportingEngine.Started)
            {
                this.notifyIcon.Text = String.Format("{0} - Reporting Engine Running", 
                    AppConfiguration.ApplicationName);
            }
            else
            {
                this.notifyIcon.Text = String.Format("{0} - Reporting Engine Stopped", 
                    AppConfiguration.ApplicationName);
            }

            this.autoStarted = false;

            int backupLookupMinutes = Properties.Settings.Default.CheckForBackupAfterMins;
            int timeout = backupLookupMinutes * MINUTE_MILLISECONDS;
            this.backupTimer.Interval = timeout;
            this.backupTimer.Start();

            int autoReminderLookupMinutes = Properties.Settings.Default.CheckForAutoRemindersAfterMins;
            timeout = autoReminderLookupMinutes * MINUTE_MILLISECONDS;
            this.autoReminderTimer.Interval = timeout;
            this.autoReminderTimer.Start();
        }

        void reportingEngine_LogChanged(object sender, ReportingEngineEventArgs e)
        {
            string logTemplate = @"[{0}] - {1}";
            //string log = String.Empty;
            //if (e.Type == ReportingEngineEventArgs.EventType.LOG_EVENT)
            //{
            //    log = String.Format(logTemplate, DateTime.Now, e.LogText);
            //}

            if (e.Type == ReportingEngineEventArgs.EventType.OPERATION_COMPLETED)
            {
                btnStopEngine_Click(null, null);
            }

            try
            {
                //if (lstLog.Items.Count > Properties.Settings.Default.MaximunLogEntry)
                if (logDataTable.Rows.Count > Properties.Settings.Default.MaximunLogEntry)
                {
                    if (!Directory.Exists(AppConfiguration.LogFileDirectory))
                    {
                        Directory.CreateDirectory(AppConfiguration.LogFileDirectory);
                    }
                    string logFilename = String.Format(@"{0}\AutoSave[{1}].txt",
                        AppConfiguration.LogFileDirectory, DateTime.Now.Ticks.ToString());
                    StreamWriter sWriter = new StreamWriter(logFilename);
                    //foreach (string line in lstLog.Items)
                    foreach (DataRow row in logDataTable.Rows)
                    {
                        string line = string.Format(logTemplate, row[0], row[1]);
                        sWriter.WriteLine(line);
                        sWriter.Flush();
                    }
                    sWriter.Close();
                    //lstLog.Items.Clear();
                    logDataTable.Rows.Clear();
                }
                else
                {
                    //lstLog.Items.Add(log);
                    DataRow row = logDataTable.NewRow();
                    row[0] = DateTime.Now;
                    row[1] = e.LogText;
                    logDataTable.Rows.Add(row);
                }
                Application.DoEvents();
            }
            catch { }

            //if (lstLog.Items.Count > 0) btnClearLog.Enabled = true;
            if (logDataTable.Rows.Count > 0) btnClearLog.Enabled = true;
            else btnClearLog.Enabled = false;
        }
        #endregion

        #region Main Control
        private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            this.Show();
            this.WindowState = FormWindowState.Normal;
            this.ShowInTaskbar = true;
        }

        private void ReportingEngineGUI_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (forceRestart)
            {
                e.Cancel = false;
                try
                {
                    this.backupTimer.Stop();
                    reportingEngine.Stop();
                    reportingEngine.Close();
                }
                catch { }
                return;
            }
            DialogResult response = MessageBox.Show(this,
                String.Format("Are you sure you want to exit {0}?\nClicking NO will only hide the application but not closing it", 
                    AppConfiguration.ApplicationName),
                String.Format("{0} - Confirm close", AppConfiguration.ApplicationName),
                MessageBoxButtons.YesNo, MessageBoxIcon.Question);

            if (response == System.Windows.Forms.DialogResult.Yes)
            {
                this.backupTimer.Stop();
                reportingEngine.Stop();
                reportingEngine.Close();
            }
            else
            {
                this.Hide();
                this.ShowInTaskbar = false;
                e.Cancel = true;
            }
        }

        private void ReportingEngineGUI_Load(object sender, EventArgs e)
        {
            //LoadConfiguredModems();
            //if (modems.Count > 0)
            //{
            //    //btnStartEngine_Click(null, null);
            //    btnStartEngine.Enabled = true;
            //    btnStopEngine.Enabled = false;
            //}
            //else
            //{
            //    btnStartEngine.Enabled = false;
            //    btnStopEngine.Enabled = false;
            //}
        }

        private void btnStartEngine_Click(object sender, EventArgs e)
        {
            try
            {
                if (modems.Count > 0)
                {
                    if (reportingEngine != null)
                    {
                        reportingEngine.Close();
                        reportingEngine = null;
                    }

                    reportingEngine = new Engine(modems, AppConfiguration.SameMonthReporting);
                    //reportingEngine.ChangingLog += new ReportingEngine.ChangingLogHandler(reportingEngine_ChangingLog);
                    reportingEngine.LogChanged += new EventHandler<ReportingEngineEventArgs>(reportingEngine_LogChanged);

                    bool started = reportingEngine.Start();
                    if (started)
                    {
                        btnStopEngine.Enabled = true;
                        btnStartEngine.Enabled = false;
                        gboConfiguredModems.Enabled = false;
                        gboModem.Enabled = false;
                        this.notifyIcon.Text = String.Format("{0} - Reporting Engine is Running", 
                            AppConfiguration.ApplicationName);
                    }
                    else
                    {
                        MessageBox.Show(this, "SMS Reporting Engine did not start", 
                            String.Format("{0} - Fatal Error", AppConfiguration.ApplicationName),
                            MessageBoxButtons.OK, MessageBoxIcon.Stop);
                        this.notifyIcon.Text = String.Format("{0} - Reporting Engine Stopped Running", 
                            AppConfiguration.ApplicationName);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(this, ex.Message, 
                    String.Format("{0} - Fatal Error", AppConfiguration.ApplicationName),
                    MessageBoxButtons.OK, MessageBoxIcon.Stop);
            }
        }

        private void btnStopEngine_Click(object sender, EventArgs e)
        {
            try
            {
                reportingEngine.Stop();
                btnStartEngine.Enabled = true;
                btnStopEngine.Enabled = false;
                gboConfiguredModems.Enabled = true;
                gboModem.Enabled = true;
                this.notifyIcon.Text = String.Format("{0} - Reporting Engine Stopped Running",
                    AppConfiguration.ApplicationName);
            }
            catch (Exception ex)
            {
                MessageBox.Show(this, ex.Message, String.Format("{0} - Fatal Error", AppConfiguration.ApplicationName),
                    MessageBoxButtons.OK, MessageBoxIcon.Stop);
            }
        }

        private void btnClearLog_Click(object sender, EventArgs e)
        {
            //lstLog.Items.Clear();
            logDataTable.Rows.Clear();
        }

        private void btnSaveToTextFile_Click(object sender, EventArgs e)
        {
            saveFileDialog.InitialDirectory = AppConfiguration.LogFileDirectory;
            DialogResult response = saveFileDialog.ShowDialog(this);
            if (response == System.Windows.Forms.DialogResult.OK)
            {
                try
                {
                    Cursor.Current = Cursors.WaitCursor;
                    Application.DoEvents();
                    //StringBuilder sBuilder = new StringBuilder();
                    StreamWriter sWriter = new StreamWriter(saveFileDialog.FileName);
                    //foreach (string log in lstLog.Items)
                    string logTemplate = @"[{0}] - {1}";
                    foreach (DataRow row in logDataTable.Rows)
                    {
                        string log = string.Format(logTemplate, row[0], row[1]);
                        sWriter.WriteLine(log);
                        sWriter.Flush();
                    }
                    sWriter.Close();
                    Cursor.Current = Cursors.Default;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(this,
                        String.Format("Could not save log file. {0}{0}Error Details:{0}{1}", Environment.NewLine, ex.Message),
                        String.Format("{0} - Error Saving Log", AppConfiguration.ApplicationName),
                        MessageBoxButtons.OK, MessageBoxIcon.Error);
                    Cursor.Current = Cursors.Default;
                }
            }
        }
        #endregion

        #region Modems Configuration Tab
        #region Private Event Handlers
        private void tabPageModemsConfigurations_Enter(object sender, EventArgs e)
        {
            if (!tabPageModemsConfigurationLoaded)
            {
                PopulateModemSettingComboBoxes();
                btnAddModem.Enabled = false;
                LoadConfiguredModems();

                tabPageModemsConfigurationLoaded = true;
            }
        }

        private void btnTest_Click(object sender, EventArgs e)
        {
            btnTest.Enabled = false;
            btnAddModem.Enabled = false;
            Cursor.Current = Cursors.WaitCursor;

            try
            {
                string portName = cboCOMPortName.Text;
                int baudRate = int.Parse(cboBaudRate.Text);
                int timeout = int.Parse(cboTimeout.Text);
                GsmCommMain comm = new GsmCommMain(portName, baudRate, timeout);
                try
                {
                    comm.Open();
                    while (!comm.IsConnected())
                    {
                        Cursor.Current = Cursors.Default;
                        DialogResult response = MessageBox.Show(this, "No phone/modem connected",
                            "Connection setup", MessageBoxButtons.RetryCancel, MessageBoxIcon.Exclamation);
                        if (response == DialogResult.Cancel)
                        {
                            gboModemDetails.Visible = false;
                            comm.Close();
                            Cursor.Current = Cursors.Default;
                            btnTest.Enabled = true;
                            return;
                        }
                        Cursor.Current = Cursors.WaitCursor;
                    }

                    LoadModemDetails(comm);
                    if (comm.IsOpen()) comm.Close();
                    this.testedPortName = portName;
                    this.testedBaudRate = baudRate;
                    this.testedTimeout = timeout;
                    MessageBox.Show(this, "Successfully connected to the phone.", "Connection setup",
                        MessageBoxButtons.OK, MessageBoxIcon.Information);
                    Cursor.Current = Cursors.Default;
                    btnTest.Enabled = true;
                    btnAddModem.Enabled = true;
                    return;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(this, "Connection error: " + ex.Message, "Connection setup",
                        MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    gboModemDetails.Visible = false;
                    Cursor.Current = Cursors.Default;
                    btnTest.Enabled = true;
                    return;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(this, ex.Message, "Modem Configuration Test",
                    MessageBoxButtons.OK, MessageBoxIcon.Warning);
                gboModemDetails.Visible = false;
                Cursor.Current = Cursors.Default;
                btnTest.Enabled = true;
                return;
            }
        }

        private void cboCOMPortName_TextUpdate(object sender, EventArgs e)
        {
            btnAddModem.Enabled = false;
        }

        private void cboBaudRate_TextUpdate(object sender, EventArgs e)
        {
            btnAddModem.Enabled = false;
        }

        private void cboTimeout_TextUpdate(object sender, EventArgs e)
        {
            btnAddModem.Enabled = false;
        }

        private void cboCOMPortName_SelectedIndexChanged(object sender, EventArgs e)
        {
            btnAddModem.Enabled = false;
        }

        private void cboBaudRate_SelectedIndexChanged(object sender, EventArgs e)
        {
            btnAddModem.Enabled = false;
        }

        private void cboTimeout_SelectedIndexChanged(object sender, EventArgs e)
        {
            btnAddModem.Enabled = false;
        }

        private void btnAddModem_Click(object sender, EventArgs e)
        {
            try
            {
                btnAddModem.Enabled = false;
                Application.DoEvents();

                GsmCommMain GSMCommunication = new GsmCommMain(testedPortName, testedBaudRate, testedTimeout);
                GSMCommunication.Open();
                bool connected = GSMCommunication.IsConnected();
                //string modemName = GSMCommunication.GetCurrentOperator().TheOperator;

                if (connected)
                {
                    LoadModemDetails(GSMCommunication);
                    if (!GSMCommunication.IsOpen()) GSMCommunication.Open();
                    string serialNumber = GSMCommunication.IdentifyDevice().SerialNumber;

                    if (this.modems.Count > 0)
                    {
                        foreach (Modem modem in this.modems)
                        {
                            string serial = modem.IdentifyDevice().SerialNumber;
                            if (serialNumber == serial)
                            {
                                MessageBox.Show(this,
                                    String.Format("Modem is already added in different port name.\nThe modem is using {0}",
                                        modem.PortName),
                                    "Modem Setup Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                                return;
                            }
                        }
                        int id = Modem.AddModem(GSMCommunication);
                        GSMCommunication.Close();
                        Modem m = new Modem(id);
                        this.modems.Add(m);

                        ListItem i = new ListItem();
                        i.Value = m;
                        i.Text = lblOperatorName.Text;
                        lstConfiguredModems.Items.Add(i);
                        LoadPreferedPrefices(m);
                        //Modem.AddModem(modemName, testedPortName, testedBaudRate, testedTimeout);
                    }
                    else
                    {
                        int id = Modem.AddModem(GSMCommunication);
                        GSMCommunication.Close();
                        Modem m = new Modem(id);
                        this.modems.Add(m);
                        if (this.reportingEngine != null) this.reportingEngine.AddModem(m);

                        ListItem i = new ListItem();
                        i.Text = lblOperatorName.Text;
                        i.Value = m;
                        lstConfiguredModems.Items.Add(i);
                        LoadPreferedPrefices(m);
                        //Modem.AddModem(GSMCommunication.GetCurrentOperator().TheOperator, testedPortName,
                        //    testedBaudRate, testedTimeout);
                    }
                }
                else
                {
                    MessageBox.Show(this, "No phone/modem connected", "Modem Setup Error",
                        MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                if (lstConfiguredModems.SelectedIndex == -1) lstConfiguredModems.SelectedIndex = 0;
                HandleButtons();
                btnAddModem.Enabled = false;
            }
            catch (Exception ex)
            {
                MessageBox.Show(this, ex.Message, "Modem Setup Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                btnAddModem.Enabled = true;
            }
        }

        private void lstConfiguredModems_SelectedIndexChanged(object sender, EventArgs e)
        {
            int index = lstConfiguredModems.SelectedIndex;
            if (index != -1)
            {
                ListItem item = (ListItem)lstConfiguredModems.SelectedItem;
                Modem modem = (Modem)item.Value;
                GsmCommMain modemComm = modem.Communication;

                Cursor.Current = Cursors.WaitCursor;
                Application.DoEvents();
                LoadModemDetails(modemComm);
                LoadPreferedPrefices(modem);
                HandleButtons();
                Cursor.Current = Cursors.Default;
            }
        }        

        private void btnRemovePrefix_Click(object sender, EventArgs e)
        {
            if (lstConfiguredModems.SelectedIndex != -1)
            {
                if (this.lstPhonePrefices.Items.Count > 0)
                {
                    if (lstPhonePrefices.SelectedIndex == -1) lstPhonePrefices.SelectedIndex = 0;
                }
                else return;

                int selectedIndex = lstPhonePrefices.SelectedIndex;
                ListItem item = (ListItem)lstPhonePrefices.SelectedItem;
                lstPhonePrefices.Items.Remove(item);
                selectedIndex--;

                if (lstPhonePrefices.Items.Count > 0)
                {
                    btnRemovePrefix.Enabled = true;
                    if (selectedIndex == -1) selectedIndex++;
                    lstPhonePrefices.SelectedIndex = selectedIndex;
                }

                ListItem i = (ListItem)lstConfiguredModems.SelectedItem;
                Modem modem = (Modem)i.Value;
                foreach (string prefix in modem.PreferedPrefices)
                {
                    if (item.Text == prefix)
                    {
                        modem.PreferedPrefices.Remove(prefix);
                        break;
                    }
                }
                modem.SavePreferedPrefices();
                LoadPreferedPrefices(modem);
                HandleButtons();
            }
            else
            {
                MessageBox.Show(this, "Please select a modem to associate the prefix with this prefix",
                    "Modem Configuration", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
        }

        private void btnRemoveModem_Click(object sender, EventArgs e)
        {
            if (this.lstConfiguredModems.Items.Count > 0)
            {
                if (this.lstConfiguredModems.SelectedIndex == -1) this.lstConfiguredModems.SelectedIndex = 0;
            }
            else return;

            int selectedIndex = this.lstConfiguredModems.SelectedIndex;
            ListItem item = (ListItem)this.lstConfiguredModems.SelectedItem;
            Modem modem = (Modem)item.Value;
            modem.Close();
            modem.RemoveInDB();
            this.lstConfiguredModems.Items.Remove(item);
            this.modems.Remove(modem);
            if (this.reportingEngine != null) this.reportingEngine.RemoveModem(modem);
            selectedIndex--;

            if (this.modems.Count > 0)
            {
                btnRemoveModem.Enabled = true;
                if (selectedIndex == -1) selectedIndex++;
                this.lstConfiguredModems.SelectedIndex = selectedIndex;
            }
            HandleButtons();
        }

        private void btnAddPrefix_Click(object sender, EventArgs e)
        {
            if (lstConfiguredModems.SelectedIndex != -1)
            {
                ListItem item = (ListItem)lstConfiguredModems.SelectedItem;
                Modem modem = (Modem)item.Value;
                modem.PreferedPrefices.Add(txtPhonePrefix.Text);
                modem.SavePreferedPrefices();
                txtPhonePrefix.Clear();
                LoadPreferedPrefices(modem);
                HandleButtons();
            }
            else
            {
                MessageBox.Show(this, "Please select a modem to associate the prefix with this prefix",
                    "Modem Configuration", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
        }

        private void txtPhonePrefix_TextChanged(object sender, EventArgs e)
        {
            if (txtPhonePrefix.Text.Length > 0) btnAddPrefix.Enabled = true;
            else btnAddPrefix.Enabled = false;
        }
        #endregion

        private void PopulateModemSettingComboBoxes()
        {
            string[] portNames = SerialPort.GetPortNames();
            foreach (string portName in portNames) cboCOMPortName.Items.Add(portName);
            if (portNames.Length > 0) cboCOMPortName.Text = portNames[0];

            cboBaudRate.Items.Add("9600");
            cboBaudRate.Items.Add("19200");
            cboBaudRate.Items.Add("38400");
            cboBaudRate.Items.Add("57600");
            cboBaudRate.Items.Add("115200");
            cboBaudRate.Text = GsmCommMain.DefaultBaudRate.ToString();

            cboTimeout.Items.Add("150");
            cboTimeout.Items.Add("300");
            cboTimeout.Items.Add("600");
            cboTimeout.Items.Add("900");
            cboTimeout.Items.Add("1200");
            cboTimeout.Items.Add("1500");
            cboTimeout.Items.Add("1800");
            cboTimeout.Items.Add("2000");
            cboTimeout.Items.Add("3000");
            cboTimeout.Text = GsmCommMain.DefaultTimeout.ToString();
        }

        private void LoadModemDetails(GsmCommMain modem)
        {
#if DEBUG
            lblManufacturer.Text = "Testing Manufacturer";
            lblModel.Text = "Testing Model";
            lblRevision.Text = "Testing Revision";
            lblSerialNumber.Text = "Testing Serial Number";
            lblSignalStrength.Text = String.Format("Testing signal: {0} dBm  {1} asu", 12, 14);
            lblSMSCenterNumber.Text = "Test SMS Center Number";
            lblOperatorName.Text = "Testing Operator Name";
            lblPortName.Text = "Testing Port Name";
            lblBaudRate.Text = "Testing Baud Rate";
            lblTimeout.Text = "Testing Timeout";

            gboModemDetails.Visible = true;
#else
       
            try
            {
                if (!modem.IsOpen())
                {
                    modem.Open();
                }
                IdentificationInfo identificationInfo = new IdentificationInfo();
                try
                {
                    identificationInfo = modem.IdentifyDevice();
                }
                catch { }
                string manufacturer = identificationInfo.Manufacturer;
                if (manufacturer.Length > 20) manufacturer = manufacturer.Substring(0, 20).Trim() + "...";

                lblManufacturer.Text = manufacturer;
                lblModel.Text = identificationInfo.Model;
                lblRevision.Text = identificationInfo.Revision;
                lblSerialNumber.Text = identificationInfo.SerialNumber;

                SignalQualityInfo signalInfo = new SignalQualityInfo(0, 0);
                int dbm = 0;
                int asu = 0;
                try
                {
                    signalInfo = modem.GetSignalQuality();
                    asu = signalInfo.SignalStrength;
                    dbm = (2 * asu) - 113;  // Just copied it from Wikipedia
                }
                catch { }
                lblSignalStrength.Text = String.Format("{0} dBm  {1} asu", dbm, asu);

                AddressData data = new AddressData(String.Empty, 0);
                try
                {
                    data = modem.GetSmscAddress();
                }
                catch { }
                lblSMSCenterNumber.Text = data.Address;

                OperatorInfo operatorInfo = null;
                string operatorName = String.Empty;
                try
                {
                    operatorInfo = modem.GetCurrentOperator();
                    operatorName = operatorInfo.TheOperator;
                }
                catch { }
                if (operatorInfo != null)
                {
                    if (operatorInfo.Format == OperatorFormat.Numeric)
                    {
                        string mobileNetworkCode = operatorInfo.TheOperator;
                        operatorName = Utilities.GetModemServiceOperator(mobileNetworkCode);
                    }
                }

                if (String.IsNullOrEmpty(operatorName)) lblOperatorName.Text = "NOT KNOWN/AVAILABLE";
                else lblOperatorName.Text = operatorName;

                lblPortName.Text = modem.PortName;
                lblBaudRate.Text = modem.BaudRate.ToString();
                lblTimeout.Text = modem.Timeout.ToString();

                gboModemDetails.Visible = true;
            }
            catch { }
            finally
            {
                if (modem.IsOpen()) modem.Close();
            }
#endif
        }        

        private void HandleButtons()
        {
            if (lstConfiguredModems.Items.Count > 0)
            {
                btnRemoveModem.Enabled = true;
                gboNumberPrefices.Enabled = true;
                btnStartEngine.Enabled = true;
                btnStopEngine.Enabled = false;
            }
            else
            {
                btnRemoveModem.Enabled = false;
                gboNumberPrefices.Enabled = false;
                btnStartEngine.Enabled = false;
                btnStopEngine.Enabled = false;
            }

            if (lstPhonePrefices.Items.Count > 0) btnRemovePrefix.Enabled = true;
            else btnRemovePrefix.Enabled = false;
        }

        private void LoadPreferedPrefices(Modem modem)
        {
            lstPhonePrefices.Items.Clear();
            foreach (string prefix in modem.PreferedPrefices)
            {
                ListItem i = new ListItem();
                i.Text = prefix;
                i.Value = prefix;
                lstPhonePrefices.Items.Add(i);
            }
        }
        #endregion

        #region Private Shared
        private void LoadConfiguredModems()
        {
            if (configuredModemsLoaded) return;

            string query = @"SELECT [ModemSettingNo],[ModemName],[PortName],[BaudRate],[WriteTimeout]
                FROM [ModemSettings]";
            DataTable dataTable = GenericDataAccess.RunSelectQuery(query);
            foreach (DataRow row in dataTable.Rows)
            {
                int DBModemNo = Int32.Parse(row["ModemSettingNo"].ToString());
                Modem modem = new Modem(DBModemNo);
                string name = row["ModemName"].ToString();
                if ((modem.LastError != null) && (this.autoStarted == false))
                {
#if DEBUG
#else
                    MessageBox.Show(this, String.Format("{0} - {1}", name, modem.LastError.Message),
                        String.Format("{0}: Connection Error", name), MessageBoxButtons.OK, MessageBoxIcon.Stop);

                    DialogResult response = MessageBox.Show(this,
                        String.Format("Do you want to remove {0} modem configuration and all associated data?", name),
                        String.Format("{0} - Invalid Modem Configuration [{1}]", AppConfiguration.ApplicationName, name),
                        MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                    if (response == System.Windows.Forms.DialogResult.Yes) modem.RemoveInDB();
#endif
                }
                else
                {
                    if (modem.CanConnect)
                    {
                        ListItem i = new ListItem();
                        i.Text = name;
                        i.Value = modem;
                        lstConfiguredModems.Items.Add(i);
                        this.modems.Add(modem);
                        LoadPreferedPrefices(modem);
                    }
                }
            }

#if DEBUG
            var degubbingModem = Modem.CreateDebuggingModem();
            if (degubbingModem.CanConnect)
            {
                ListItem i = new ListItem();
                i.Text = degubbingModem.Name;
                i.Value = degubbingModem;
                lstConfiguredModems.Items.Add(i);
                this.modems.Add(degubbingModem);
                LoadPreferedPrefices(degubbingModem);
            }

#endif
            HandleButtons();
            configuredModemsLoaded = true;
        }

        DataTable logDataTable = null;
        private void reportingEngine_ChangingLog(object sender, ReportingEngineEventArgs e)
        {
            string logTemplate = @"[{0}] - {1}";
            //string log = String.Empty;
            //if (e.Type == ReportingEngineEventArgs.EventType.LOG_EVENT)
            //{
            //    log = String.Format(logTemplate, DateTime.Now, e.LogText);
            //}

            if (e.Type == ReportingEngineEventArgs.EventType.OPERATION_COMPLETED)
            {
                btnStopEngine_Click(null, null);
            }

            try
            {
                //if (lstLog.Items.Count > Properties.Settings.Default.MaximunLogEntry)
                if (logDataTable.Rows.Count > Properties.Settings.Default.MaximunLogEntry)
                {
                    string logFilename = String.Format(@"{0}\AutoSave[{1}].txt",
                        AppConfiguration.ApplicationName, DateTime.Now.Ticks.ToString());
                    StreamWriter sWriter = new StreamWriter(logFilename);
                    //foreach (string line in lstLog.Items)
                    foreach (DataRow row in logDataTable.Rows)
                    {
                        string line = string.Format(logTemplate, row[0], row[1]);
                        sWriter.WriteLine(line);
                        sWriter.Flush();
                    }
                    sWriter.Close();
                    //lstLog.Items.Clear();
                    logDataTable.Rows.Clear();
                }
                else
                {
                    //lstLog.Items.Add(log);
                    DataRow row = logDataTable.NewRow();
                    row[0] = DateTime.Now;
                    row[1] = e.LogText;
                    logDataTable.Rows.Add(row);
                }
                Application.DoEvents();
            }
            catch { }
            
            //if (lstLog.Items.Count > 0) btnClearLog.Enabled = true;
            if (dgvLog.Rows.Count > 0) btnClearLog.Enabled = true;
            else btnClearLog.Enabled = false;
        }
        #endregion

        #region Testing Page
        private void btnQueueInOutbox_Click(object sender, EventArgs e)
        {
            txtSystemReply.Clear();
            if (String.IsNullOrEmpty(txtPhoneNumber.Text))
            {
                MessageBox.Show(this, "Phone number is missing", AppConfiguration.ApplicationName,
                    MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                txtPhoneNumber.Focus();
                return;
            }

            if (String.IsNullOrEmpty(txtMessage.Text))
            {
                MessageBox.Show(this, "Provide message contents", AppConfiguration.ApplicationName,
                    MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                txtMessage.Focus();
                return;
            }

            GenericTools.ShortMessage.SendDBSMS(txtPhoneNumber.Text, txtMessage.Text);
            txtSystemReply.AppendText("Added SMS into outbox");
            txtSystemReply.AppendText(Environment.NewLine);
            txtSystemReply.AppendText(String.Format("[{0}] {1}", txtPhoneNumber.Text, txtMessage.Text));
        }

        private void btnSendMessage_Click(object sender, EventArgs e)
        {
            txtSystemReply.Clear();
            string message = txtMessage.Text;
            string number = txtPhoneNumber.Text;

            string replyMessage = String.Empty;
            string keyword = String.Empty;
            if (message.Trim().Contains('.')) keyword = message.Substring(0, 4).ToLower();
            else keyword = message.Trim().ToLower();

            ReportingMode mode = ReportingMode.DEFAULT;
            SMSReportingFormat smsFormat = Properties.Settings.Default.SMSFormat;
            DataInputingMethod inputMethod = DataInputingMethod.SMS;
            switch (keyword)
            {
                case "reg.":
                    #region Registration
                    txtSystemReply.AppendText("Starting processing Registration:");
                    txtSystemReply.AppendText(Environment.NewLine);
                    txtSystemReply.AppendText(String.Format("[{0}] {1}", number, message));
                    txtSystemReply.AppendText(Environment.NewLine);
                    txtSystemReply.AppendText(Environment.NewLine);

                    string registrationText = message.Substring(4);
                    RegistrationInfo registrationInfo = new RegistrationInfo(number, registrationText);
                    
                    if (chbSaveInDB.Checked) registrationInfo.Register();

                    replyMessage = registrationInfo.ErrorText;
                    MessageBox.Show(this, String.Format("[{0}] - {1}", number, replyMessage), "Received Message",
                        MessageBoxButtons.OK, MessageBoxIcon.Information);

                    txtSystemReply.AppendText("Completed processing Registration:");
                    txtSystemReply.AppendText(Environment.NewLine);
                    txtSystemReply.AppendText(String.Format("[{0}] {1}", number, message));
                    txtSystemReply.AppendText(Environment.NewLine);
                    txtSystemReply.AppendText(Environment.NewLine);

                    txtSystemReply.AppendText("Received Message:");
                    txtSystemReply.AppendText(Environment.NewLine);
                    txtSystemReply.AppendText(replyMessage);
                    #endregion
                    break;

                case "help":
                case "msaada":
                case "assistance":
                    txtSystemReply.AppendText("Starting processing Assistance Request");
                    txtSystemReply.AppendText(Environment.NewLine);
                    txtSystemReply.AppendText(String.Format("[{0}] {1}", number, message));
                    if (chbSaveInDB.Checked) Utilities.SendAssistance(number);
                    break;

                case "rep.":
                    #region Report Request
                    txtSystemReply.AppendText("Starting processing Report Request:");
                    txtSystemReply.AppendText(Environment.NewLine);
                    txtSystemReply.AppendText(String.Format("[{0}] {1}", number, message));
                    txtSystemReply.AppendText(Environment.NewLine);
                    txtSystemReply.AppendText(Environment.NewLine);

                    string reportingQuery = message.Substring(4).Trim();
                    ReportingType type = ReportingType.REQUEST;
                    mode = ReportingMode.DEFAULT;
                    if (AppConfiguration.SameMonthReporting) mode |= ReportingMode.ALLOW_SAME_MONTH_REPORTING;

                    ReportProcessor reportRequestProcessor = new ReportProcessor(number, reportingQuery, type, mode, smsFormat, inputMethod);
                    replyMessage = reportRequestProcessor.GetReport();
                    if (reportRequestProcessor.HasError) replyMessage = reportRequestProcessor.ErrorText;

                    MessageBox.Show(this, String.Format("[{0}] - {1}", number, replyMessage), "Received Message",
                        MessageBoxButtons.OK, MessageBoxIcon.Information);

                    txtSystemReply.AppendText("Completed processing Report Request:");
                    txtSystemReply.AppendText(Environment.NewLine);
                    txtSystemReply.AppendText(String.Format("[{0}] {1}", number, message));
                    txtSystemReply.AppendText(Environment.NewLine);
                    txtSystemReply.AppendText(Environment.NewLine);
                    
                    txtSystemReply.AppendText("Received Message:");
                    txtSystemReply.AppendText(Environment.NewLine);
                    txtSystemReply.AppendText(replyMessage);
                    #endregion
                    break;

                default:
                    #region Reporting and Others
                    txtSystemReply.AppendText("Starting processing Report:");
                    txtSystemReply.AppendText(Environment.NewLine);
                    txtSystemReply.AppendText(String.Format("[{0}] {1}", number, message));
                    txtSystemReply.AppendText(Environment.NewLine);
                    txtSystemReply.AppendText(Environment.NewLine);

                    string reportingText = message.Trim();
                    mode = ReportingMode.DEFAULT;
                    if (AppConfiguration.SameMonthReporting) mode |= ReportingMode.ALLOW_SAME_MONTH_REPORTING;
                    
                    ReportProcessor reportProcessor = new ReportProcessor(number, reportingText, mode, smsFormat, inputMethod);
                    reportProcessor.ReportBussinessRulesFailed += ReportProcessor.HandleMTUHAMCReport;
                    reportProcessor.SavingReport += ReportProcessor.HandleInconsitentReports;

                    if (chbSaveInDB.Checked) reportProcessor.Submit();
                    else
                    {
                        replyMessage = reportProcessor.ErrorText;
                        if (reportProcessor.HasError)
                        {
                            bool hasError = default(bool);                            
                            var reportingError = ReportProcessor.ProcessStockReportingMessage(number, 
                                reportingText, reportProcessor.ErrorText, reportProcessor.ErrorTextLabelID, out hasError, smsFormat);
                            replyMessage = reportingError.ErrorText;
                        }                        

                        MessageBox.Show(this, String.Format("[{0}] - {1}", number, replyMessage), "Received Message",
                            MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }

                    txtSystemReply.AppendText("Completed processing Report:");
                    txtSystemReply.AppendText(Environment.NewLine);
                    txtSystemReply.AppendText(String.Format("[{0}] {1}", number, message));
                    txtSystemReply.AppendText(Environment.NewLine);
                    txtSystemReply.AppendText(Environment.NewLine);

                    txtSystemReply.AppendText("Received Message:");
                    txtSystemReply.AppendText(Environment.NewLine);
                    txtSystemReply.AppendText(replyMessage);
                    #endregion
                    break;
            }
        }
        #endregion

        #region Settings
        private void tabPageSettings_Enter(object sender, EventArgs e)
        {
            string lastBackedUp = Utilities.GetSetting(LAST_BACKUP);
            DateTime lastBackupDate = DateTime.Now;
            try
            {
                lastBackupDate = DateTime.Parse(lastBackedUp);
                lblAutoBackup.Text = String.Format("Date of last auto backup: {0}", lastBackupDate.ToString());
                TimeSpan timeSpan = DateTime.Now - lastBackupDate;
                if (timeSpan.Days < 7) lblAutoBackup.ForeColor = Color.Blue;
                else lblAutoBackup.ForeColor = Color.Red;
            }
            catch
            {
                lblAutoBackup.Text = "Date of last auto-backup could not be determined";
                lblAutoBackup.ForeColor = Color.Red;
            }

            if (!tabPageSettingsLoaded)
            {
                DataTable dataTable = Utilities.GetBlockedNumbers();
                foreach (DataRow row in dataTable.Rows)
                {
                    ListItem item = new ListItem();
                    item.Text = row["PhoneNumber"].ToString();
                    item.Value = row["PhoneNumber"].ToString();
                    lstBlockedNumbers.Items.Add(item);
                }
                if (dataTable.Rows.Count < 1) btnRemoveBlockedNumber.Enabled = false;
                else btnRemoveBlockedNumber.Enabled = true;

                string setting = Utilities.GetSetting(CREATE_BACKUP_AFTER);
                int createBackupAfterDays = 1;  // Default is 1
                if (String.IsNullOrEmpty(setting))
                {
                    createBackupAfterDays = Properties.Settings.Default.CreateBackupAfter;
                    Utilities.SetSetting(CREATE_BACKUP_AFTER, createBackupAfterDays.ToString());
                }
                else createBackupAfterDays = Int32.Parse(setting);
                nudDays.Value = createBackupAfterDays;                

                setting = Utilities.GetSetting(BACKUP_FOLDER);
                string autoBackupFolder = String.Empty;
                if (String.IsNullOrEmpty(setting))
                {
                    autoBackupFolder = Properties.Settings.Default.BackupFolder;
                    Utilities.SetSetting(BACKUP_FOLDER, autoBackupFolder);
                }
                else autoBackupFolder = setting;
                txtAutobackupLocation.Text = autoBackupFolder;

                setting = Utilities.GetSetting(COMPRESS_BACKUP);
                bool compressBackupFiles = true;
                if (String.IsNullOrEmpty(setting))
                {
                    compressBackupFiles = Properties.Settings.Default.CompressBackup;
                    Utilities.SetSetting(COMPRESS_BACKUP, compressBackupFiles.ToString());
                }
                else compressBackupFiles = bool.Parse(setting);
                chkCompressAutoBackup.Checked = compressBackupFiles;

                tabPageSettingsLoaded = true;
            }
        }

        private void btnRemoveBlockedNumber_Click(object sender, EventArgs e)
        {
            if (lstBlockedNumbers.Items.Count > 0)
            {
                int index = lstBlockedNumbers.SelectedIndex;
                if (index < 0) index = 0;
                ListItem item = (ListItem)lstBlockedNumbers.Items[index];
                string phoneNumber = item.Value.ToString();
                Utilities.RemoveBlockedNumber(phoneNumber);
                lstBlockedNumbers.Items.RemoveAt(index);
                if (lstBlockedNumbers.Items.Count < 1) btnRemoveBlockedNumber.Enabled = false;
                else btnRemoveBlockedNumber.Enabled = true;
            }
        }

        private void txtNewBlockedNumber_TextChanged(object sender, EventArgs e)
        {
            if (String.IsNullOrEmpty(txtNewBlockedNumber.Text)) btnAddBlockedNumber.Enabled = false;
            else btnAddBlockedNumber.Enabled = true;
        }

        private void btnAddBlockedNumber_Click(object sender, EventArgs e)
        {
            if (!String.IsNullOrEmpty(txtNewBlockedNumber.Text))
            {
                string phoneNumber = txtNewBlockedNumber.Text;
                if (Utilities.IsNumberBlocked(phoneNumber)) return;

                Utilities.AddBlockedNumber(phoneNumber);
                ListItem item = new ListItem();
                item.Text = phoneNumber;
                item.Value = phoneNumber;
                lstBlockedNumbers.Items.Add(item);
                if (lstBlockedNumbers.Items.Count < 1) btnRemoveBlockedNumber.Enabled = false;
                else btnRemoveBlockedNumber.Enabled = true;
            }
        }
        #endregion

        private void btnBrowseBackup_Click(object sender, EventArgs e)
        {
            string previousFilter = saveFileDialog.Filter;
            saveFileDialog.Filter = "Microsoft SQL Server Backup Files|*.bak";
            DialogResult response = saveFileDialog.ShowDialog(this);
            if (response == System.Windows.Forms.DialogResult.OK)
            {
                string backupFile = saveFileDialog.FileName;
                txtBackupLocation.Text = backupFile;
                btnCreateBackup.Enabled = true;
            }
            saveFileDialog.Filter = previousFilter;
        }

        private void btnCreateBackup_Click(object sender, EventArgs e)
        {
            string previousTitle = btnCreateBackup.Text;
            btnCreateBackup.Text = @"Please wait...";
            btnCreateBackup.Enabled = false;
            Application.DoEvents();
            try
            {
                string connectionString = AppConfiguration.DBConnectionString;
                string databaseName = String.Empty;
                string[] components = connectionString.Split(';');
                foreach (string component in components)
                {
                    string componen = component.ToLower();
                    if (componen.StartsWith("initial catalog"))
                    {
                        string[] parts = component.Split('=');
                        databaseName = parts[1];
                        break;
                    }
                }
                string backupFile = saveFileDialog.FileName;
                string outPutFile = Utilities.BackupSQLDatabase(connectionString, databaseName, backupFile);
                if (chkCompressBackup.Checked)
                {
                    FileInfo fileInfo = new FileInfo(outPutFile);
                    string compressedFile = DataTransformation.Compress(fileInfo);
                    System.IO.File.Delete(outPutFile);
                    outPutFile = compressedFile;
                }
                MessageBox.Show(this,
                    String.Format("The operation completed successfully{0}.Backup file is saved in {1}",
                        Environment.NewLine, outPutFile),
                    AppConfiguration.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show(this, 
                    String.Format("The following error during the operation:{0}{1}", 
                        Environment.NewLine, ex.Message),
                    AppConfiguration.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            btnCreateBackup.Text = previousTitle;
            btnCreateBackup.Enabled = true;
        }

        private void btnBrowseAutoBackup_Click(object sender, EventArgs e)
        {
            DialogResult response = folderBrowserDialog.ShowDialog(this);
            if (response == System.Windows.Forms.DialogResult.OK)
            {
                txtAutobackupLocation.Text = folderBrowserDialog.SelectedPath;
                btnSaveAutoBackupSettings.Enabled = true;
            }
        }

        private void btnSaveAutoBackupSettings_Click(object sender, EventArgs e)
        {
            string previousTitle = btnSaveAutoBackupSettings.Text;
            btnSaveAutoBackupSettings.Text = "Please wait...";
            btnSaveAutoBackupSettings.Enabled = false;
            Application.DoEvents();

            int createBackupAfterDays = Int32.Parse(nudDays.Value.ToString());
            string autoBackupFolder = txtAutobackupLocation.Text;
            bool compressBackupFiles = chkCompressAutoBackup.Checked;

            Utilities.SetSetting(CREATE_BACKUP_AFTER, createBackupAfterDays.ToString());
            Utilities.SetSetting(BACKUP_FOLDER, autoBackupFolder);
            Utilities.SetSetting(COMPRESS_BACKUP, compressBackupFiles.ToString());

            btnSaveAutoBackupSettings.Text = previousTitle;
            btnSaveAutoBackupSettings.Enabled = true;
        }

        private void backupTimer_Tick(object sender, EventArgs e)
        {
            string lastBackedUp = Utilities.GetSetting(LAST_BACKUP);
            DateTime now = DateTime.Now;
            DateTime lastBackupDate = now;
            try
            {
                lastBackupDate = DateTime.Parse(lastBackedUp);
                TimeSpan timeSpan = now - lastBackupDate;
                
                int backupInterval = Properties.Settings.Default.CreateBackupAfter;
                if (timeSpan.Days > backupInterval) CreateBackup();
            }
            catch
            {
                string log = "Date of last auto-backup could not be determined";
                ReportingEngineEventArgs ev = new ReportingEngineEventArgs(log);
                reportingEngine_ChangingLog(null, ev);
                CreateBackup();
            }
            this.backupTimer.Start();
        }

        private void CreateBackup()
        {
            DateTime now = DateTime.Now;
            string year = now.Year.ToString();
            string month = (now.Month.ToString().Length == 2) ? now.Month.ToString() : String.Format("0{0}", now.Month);
            string day = (now.Day.ToString().Length == 2) ? now.Day.ToString() : String.Format("0{0}", now.Day);
            string hour = (now.Hour.ToString().Length == 2) ? now.Hour.ToString() : String.Format("0{0}", now.Hour); ;
            string mins = (now.Minute.ToString().Length == 2) ? now.Minute.ToString() : String.Format("0{0}", now.Minute);

            string sNow = String.Format("{0}-{1}-{2} {3}:{4}", year, month, day, hour, mins);
            string backupFile = String.Format("{0}.bak", sNow.Replace(":", ""));
            
            string backupFolder = Properties.Settings.Default.BackupFolder;
            if (!Directory.Exists(backupFolder)) Directory.CreateDirectory(backupFolder);
            
            backupFile = String.Format(@"{0}\{1}", backupFolder, backupFile);
            string log = String.Format("Creating database backup: {0}", backupFile);
            ReportingEngineEventArgs ev = new ReportingEngineEventArgs(log);
            reportingEngine_ChangingLog(null, ev);

            try
            {
                string connectionString = AppConfiguration.DBConnectionString;
                string databaseName = String.Empty;
                string[] components = connectionString.Split(';');
                foreach (string component in components)
                {
                    string componen = component.ToLower();
                    if (componen.StartsWith("initial catalog"))
                    {
                        string[] parts = component.Split('=');
                        databaseName = parts[1];
                        break;
                    }
                }
                string outPutFile = Utilities.BackupSQLDatabase(connectionString, databaseName, backupFile);
                log = String.Format("Finished creating uncompressed backup file: {0}", outPutFile);
                ev = new ReportingEngineEventArgs(log);
                reportingEngine_ChangingLog(null, ev);

                string setting = Utilities.GetSetting(COMPRESS_BACKUP);
                bool compressBackupFile = true;
                if (String.IsNullOrEmpty(setting)) compressBackupFile = true;
                else compressBackupFile = bool.Parse(setting);
                if (compressBackupFile)
                {
                    log = String.Format("Compressing backup file: {0}", outPutFile);
                    ev = new ReportingEngineEventArgs(log);
                    reportingEngine_ChangingLog(null, ev);

                    FileInfo fileInfo = new FileInfo(outPutFile);
                    string compressedFile = DataTransformation.Compress(fileInfo);

                    log = String.Format("Deleting uncompressed backup file: {0}", outPutFile);
                    ev = new ReportingEngineEventArgs(log);
                    reportingEngine_ChangingLog(null, ev);
                    System.IO.File.Delete(outPutFile);

                    outPutFile = compressedFile;
                    log = String.Format("Finished creating compressed backup file: {0}", outPutFile);
                    ev = new ReportingEngineEventArgs(log);
                    reportingEngine_ChangingLog(null, ev);
                }

                Utilities.SetSetting(LAST_BACKUP, sNow);
            }
            catch (Exception ex)
            {
                ev = new ReportingEngineEventArgs(ex.Message);
                reportingEngine_ChangingLog(null, ev);
                log = "Failed to create backup file";
                ev = new ReportingEngineEventArgs(log);
                reportingEngine_ChangingLog(null, ev);
                Utilities.LogError(ex, null);
            }
        }

        public void ForceRestart()
        {
            forceRestart = true;
        }

        private void autoReminderTimer_Tick(object sender, EventArgs e)
        {
            if (reportingEngine != null && autoReminder != null)
            {
                if (reportingEngine.Started && !autoReminderBackgroundWorker.IsBusy)
                {
                    autoReminderTimer.Stop();
                    autoReminderBackgroundWorker.RunWorkerAsync();
                }
            }
        }

        private void autoReminderBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            if (autoReminder != null)
            {
                autoReminder.SendAutomaticSMSReminder();
            }
        }

        private void autoReminderBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                if (autoReminder.TotalSentMessages > 0)
                {
                    TimeSpan timeTaken = autoReminder.TimeTakenForSendingReminders;
                    string log = string.Format(
                        "AUTO-REMINDER: Found {0} missing reports. Placed {1} messages in the outbox. " +
                        "The time taken to accomplish the task: {2:00}:{3:00}:{4:00}",
                        autoReminder.TotalMissingReports, autoReminder.TotalSentMessages,
                        timeTaken.Hours, timeTaken.Minutes, timeTaken.Seconds);
                    
                    ReportingEngineEventArgs args = new ReportingEngineEventArgs(log);
                    reportingEngine_ChangingLog(null, args);
                }
            }

            // Make sure the process repeates.
            this.autoReminderTimer.Start();
        }

        private void txtSearchLog_TextChanged(object sender, EventArgs e)
        {
            string keyword = txtSearchLog.Text;
            DataTable dataSource = dgvLog.DataSource as DataTable;
            if (dataSource != null)
            {
                if (string.IsNullOrEmpty(keyword))
                {
                    // Reset everything back to the way it was.
                    dataSource.DefaultView.RowFilter = string.Empty;
                    return;
                }

                string filterExpression = string.Format("LogDetailsColumn LIKE '%{0}%' ", keyword);
                dataSource.DefaultView.RowFilter = filterExpression;
            }
        }
    }
}